<template>
  <div style="border: 1px solid #ccc; margin-top: 10px;display: flex">
    <div>
      <!-- 工具栏 -->
      <Toolbar
          :editor="editorRef"
          :defaultConfig="toolbarConfig"
          style="border-bottom: 1px solid #ccc"
      />
      <!-- 编辑器 -->
      <Editor
          v-model="html"
          :defaultConfig="editorConfig"
          style="height: 500px; overflow-y: hidden;font-size: 18px"
          @onCreated="handleCreated"
          @onChange="handleChange"
      />
    </div>
    <div style="width: 200px; background-color: #f1f1f1;">
      <p class="menuTitle">目录</p>
      <ul class="titleContent">
        <li
            class="titleItem ellipsis"
            v-for="item in titles"
            :key="item.id"
            :type="item.type"
            :title="item.text"
            @click="goPosition(item.id)">
          {{item.text}}
        </li>
      </ul>
    </div>
    <div style="width: 200px; background-color: #f1f1f1;">
      <p class="menuTitle">评论</p>
      <ul class="titleContent">
        <li
            class="titleItem ellipsis"
            v-for="item in comments"
            :key="item.id"
            :style="{backgroundColor: item.bgColor}"
            :title="item.text"
            @click="goPosition(item.id)">
          {{item.target}}
        </li>
      </ul>
    </div>
  </div>
</template>

<script setup lang="ts">
import {ref, shallowRef, onBeforeUnmount, nextTick} from 'vue';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import {IDomEditor, SlateEditor, SlateElement, SlateNode, SlateText, SlateTransforms} from "@wangeditor/editor";
import './custom.ts'
import {getRandomLightColor,findNodeWithPath} from '@/utils/index'

  // 编辑器实例
  const editorRef = shallowRef<IDomEditor|null>(null);
  // 编辑器内容
  const html = ref('<p>Hello, WangEditor!</p>');
  // 工具栏配置
  const toolbarConfig = {};
  // 编辑器配置
  const editorConfig = {
    placeholder: '请输入内容...',
    fontSize: '18px',
    hoverbarKeys: {
      text: {
        menuKeys: ['continue','polish','comment'], // 自定义 hoverbar 菜单
      },
      comment: {
        menuKeys: ['continue','polish','comment'], // 自定义 hoverbar 菜单
      },
      showOnClick: false
    },
  };
  // 目录
  let titles = ref<any>([])
  // 评论
  let comments = ref<any>([])


  // 编辑器创建后的回调
  const handleCreated = (editor:IDomEditor) => {
    editorRef.value = editor; // 记录 editor 实例
    editorRef.value['onContinue'] = handleContinue
    editorRef.value['onPolish'] = handlePolish
    editorRef.value['onComment'] = handleComment
  };
  const handleChange = (editor:IDomEditor) => {
    getTitle(editor)
  };
  const handleContinue = (editor:IDomEditor) => {
    console.log(editor.getSelectionText(),'continue')
  }
  const handlePolish = (editor:IDomEditor) => {
    console.log(editor.getSelectionText(),'polish')
  }
  const handleComment = (editor:IDomEditor,val:string) => {
    console.log('comment',val)
    nextTick(() => {
      const bgColor = getRandomLightColor()
      SlateTransforms.setNodes(
          editor,
          { bgColor },
          // 应用到文本节点上，
          // 如果所选内容仅为文本节点的一部分，则将其拆分。
          { match: n => SlateText.isText(n), split: true }
      )
      const [parentNode] = findNodeWithPath(editor.getElemsByTypePrefix('paragraph'),editor.getSelectionText())
      comments.value.push({
        text: val,
        id:parentNode.id,
        bgColor,
        target: editor.getSelectionText(),
      })
    })
  }

  const getTitle = (editor:IDomEditor) => {
    const headers = editor.getElemsByTypePrefix('header')
    titles.value = headers.map(header => {
      const text = SlateNode.string(header)
      const { id, type } = header
      return {id,type,text}
    })
  }
  const goPosition = (id:string) => {
    editorRef.value?.scrollToElem(id) // 滚动到标题
  }
  // 组件销毁时，销毁编辑器
  onBeforeUnmount(() => {
    if (editorRef.value) {
      editorRef.value.destroy();
    }
  })
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style lang="scss" scoped>
  .menuTitle {
    margin-top: 10px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .titleContent {
    height: calc(100% - 30px);
    box-sizing: border-box;
    padding: 5px;
    overflow: auto;
    .titleItem {
      box-sizing: border-box;
      padding: 5px;
    }
    .ellipsis {
      white-space: nowrap; /* 防止文本换行 */
      overflow: hidden; /* 隐藏溢出的内容 */
      text-overflow: ellipsis; /* 显示省略号来代表被修剪的文本 */
    }
    .titleItem:hover {
      cursor: pointer;
      background: #f9f9f9;
    }
    .titleItem[type="header1"] {
      font-size: 20px;
      font-weight: bold;
    }

    .titleItem[type="header2"] {
      font-size: 16px;
      padding-left: 15px;
      font-weight: bold;
    }

    .titleItem[type="header3"] {
      font-size: 14px;
      padding-left: 30px;
    }

    .titleItem[type="header4"] {
      font-size: 12px;
      padding-left: 45px;
    }

    .titleItem[type="header5"] {
      font-size: 12px;
      padding-left: 60px;
    }
  }
</style>
